public abstract class State {
	private int velocidad;
	public int getVelocidad(){
		  return velocidad;
	  }
	  public void setVelocidad(int velocidad) {
		this.velocidad = velocidad;
	}
		
	public abstract Posicion mover(Fantasma fantasma);
	public abstract Direccion elejirDireccion(Fantasma fantasma);
	public abstract  State next(Evento i);
	public abstract int incrementarVision();
	
} 



//----------------------------------

abstract class Cazando extends State {
	
	  private String nombreEstado;

	  public void setNombreEstado(String nombreEstado) {
		this.nombreEstado = nombreEstado;
	}

	public String toString() { return nombreEstado; }
  
	  public Posicion mover(Fantasma fantasma) { 
			    System.out.println("Estado: " + this.nombreEstado);
		  return fantasma.posicionPersecucion;
	  }
	  
	  public Direccion elejirDireccion(Fantasma fantasma){
		  return fantasma.dirPersecucion;
	  }
	  	  
	  public State next(Evento i) {
	      Evento ma = (Evento)i;
	    
	      if(ma.equals(Evento.escapar)){
	    	  return new Escapando();
	      }
	    
	      if(ma.equals(Evento.morir)){
	    	  throw new RuntimeException(
	    			  "Evento: " +  i.toString()+ " no valida para el fantasma " + this.toString());
	      }
	      
	      
		return this;
	  }
	  

	  

	}

//----------------------------------

class CazandoTranquilo extends Cazando{
	
	
	  public CazandoTranquilo() { 
		  this.setNombreEstado("cazando con agresividad Tranquila");
		  this.setVelocidad(3);
		  }
	
	  public State next(Evento i) {
		  
	      Evento mb = (Evento)i;
		  if(mb.equals(Evento.molestar)){
	    	  return new CazandoMolesto();
	    	  }		  
		  return super.next(mb);
		  
	  }


	public int incrementarVision() {
		return 0;
	}

	  


	
}

class CazandoMolesto extends Cazando{
	
	  public CazandoMolesto() { 
		  this.setNombreEstado("cazando con agresividad Molesta");
		  this.setVelocidad(2);
		  }
  
	public State next(Evento i) {
		  
	      Evento mb = (Evento)i;
		  if(mb.equals(Evento.molestar)){
	    	  return new CazandoFurioso();
	    	  }		  
		  return super.next(mb);

		  
	  }

	@Override
	public int incrementarVision() {
		return 1;
	}

}

class CazandoFurioso extends Cazando{
	
	  public CazandoFurioso() { 
		  this.setNombreEstado("cazando con agresividad Furiosa");
		  this.setVelocidad(1);
		  }
	
	public State next(Evento i) {
		  
	      Evento mb = (Evento)i;  
		  return super.next(mb);
		  
	  }

	@Override
	public int incrementarVision() {
		return 1;
	}

	
}

//----------------------------------

class Escapando extends State {

	  private String nombreEstado;
	  
	  public Escapando() { 
		  nombreEstado = "escapando";
		  this.setVelocidad(3);
		  }
	  
	  public String toString() { return nombreEstado; }
  
	  public Posicion mover(Fantasma fantasma) {
	    return fantasma.posicionEscape;
	  }
	  
	  public Direccion elejirDireccion(Fantasma fantasma){
		  return fantasma.dirEscape;
	  }
	  
	  public State next(Evento i) {
		      
	      Evento ma = (Evento)i;
	    
	      if(ma.equals(Evento.cazar))
	        return new CazandoTranquilo();
	      
	      if(ma.equals(Evento.morir)){
	    	  if (Config.debug) System.out.println("Soy presa y me comiste");
	    	  return new Muerto();
	      }
	      
	      if(ma.equals(Evento.molestar)){
	    	  throw new RuntimeException(
	    			  "Evento: " +  i.toString()+ " no valido para el fantasma " + this.toString());
	      }
	      
	      return this;
	  }

	@Override
	public int incrementarVision() {
		return 0;
	}

	    
	}

//----------------------------------


class Muerto extends State {
	
	  private String nombreEstado;

	  
	  public Muerto() { 
		  nombreEstado = "muerto";
		  this.setVelocidad(3);
	  }
	  
	  public String toString() { return nombreEstado; }

  
	  public Posicion mover(Fantasma fantasma) { 
		  //if (Config.debug) System.out.println("Estado: fantasma muerto");   
	    return fantasma.posicionInicial;
	  }
	  
	  public Direccion elejirDireccion(Fantasma fantasma){
		  return fantasma.dirInicial;
	  }
	  
	  public State next(Evento i) {
		  
	    
	      Evento ma = (Evento)i;
	      
	      if(ma.equals(Evento.molestar)){
	    	  throw new RuntimeException(
	    			  "Fantasma muerto");
	      }
	    
	      if(ma.equals(Evento.cazar))
	        return new CazandoTranquilo();
	      
	      if(ma.equals(Evento.escapar)){
	    	  throw new RuntimeException(
	    			  "Fantasma muerto");
	      }
	      if(ma.equals(Evento.morir)){
	    	  throw new RuntimeException(
	    			  "Fantasma muerto" );
	      }
		return this;
	  }

	@Override
	public int incrementarVision() {
		return 0;
	}

	}
